package cn.com.libertymutual.sp.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;

import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.util.BeanUtilExt;
import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.util.DateUtil;
import cn.com.libertymutual.core.util.enums.CoreServiceEnum;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.core.web.util.RequestUtils;
import cn.com.libertymutual.sp.dto.CommonQueryRequestDTO;
import cn.com.libertymutual.sp.dto.PrpdCode;
import cn.com.libertymutual.sp.dto.SelectDto;
import cn.com.libertymutual.sp.dto.TPrpdCodeResponseDto;
import cn.com.libertymutual.sp.dto.TQueryPolicyRequstDto;
import cn.com.libertymutual.sp.dto.TravelDto;
import cn.com.libertymutual.sp.dto.response.CountryDto;
import cn.com.libertymutual.sp.service.api.CodeRelateService;
import cn.com.libertymutual.sys.bean.SysCodeNode;
import cn.com.libertymutual.sys.bean.SysCodeRelate;
import cn.com.libertymutual.sys.bean.SysServiceInfo;
import cn.com.libertymutual.sys.dao.ISysCodeNodeDao;
import cn.com.libertymutual.sys.dao.ISysCodeRelateDao;
import cn.com.libertymutual.sys.dao.ISysServiceInfoDao;

@Service("CodeRelateService")
public class CodeRelateImpl implements CodeRelateService {
	private Logger log = LoggerFactory.getLogger(getClass());
	@Autowired
	private ISysCodeRelateDao codeRelateDao;

	@Autowired
	private ISysCodeNodeDao iSysCodeNodeDao;
	@Resource
	RestTemplate restTemplate;
	@Autowired
	private ISysServiceInfoDao iSysServiceInfoDao;
	@Autowired
	private JdbcTemplate readJdbcTemplate;

	@Resource
	private RedisUtils redisUtils;

	@Override
	public ServiceResult getSaleInitData(String codeType) {
		ServiceResult sr = new ServiceResult();
		if ("CountryCode".equals(codeType)) {
			List<SysCodeRelate> sysCode = codeRelateDao.getSaleInitData(codeType);
			List<CountryDto> codeList = new ArrayList<CountryDto>();
			for (int i = 0; i < sysCode.size(); i++) {
				CountryDto cd = new CountryDto();
				cd.setcName(sysCode.get(i).getCodeCname1());
				cd.seteName(sysCode.get(i).getCodeEname1());
				codeList.add(cd);
			}
			sr.setResult(codeList);
		} else {
			sr.setResult(codeRelateDao.getSaleInitData(codeType));
		}
		return sr;
	}

	// @Override
	// public ServiceResult findSaleInitUrlData(String userName) {
	// ServiceResult sr = new ServiceResult();
	// List<SysServiceInfo> sysUrlInfo =
	// iSysServiceInfoDao.findByUserName(userName);
	// sr.setResult(sysUrlInfo);
	// return sr;
	// }
	@Override
	public ServiceResult findSaleInitUrlData(String userName) {
		ServiceResult sr = new ServiceResult();
		List<SysServiceInfo> sysUrlInfo = (List<SysServiceInfo>) redisUtils.get(Constants.SERVICE_INFO_BY_USERNAME + userName);
		if (null != sysUrlInfo) {
			sr.setResult(sysUrlInfo);
		} else {
			List<SysServiceInfo> dbsysUrlInfo = iSysServiceInfoDao.findByUserName(userName);
			redisUtils.set(Constants.SERVICE_INFO_BY_USERNAME + userName, dbsysUrlInfo);
			sr.setResult(dbsysUrlInfo);
		}
		return sr;
	}

	@Override
	public ServiceResult getSeleCountry(String planId) {
		ServiceResult sr = new ServiceResult();
		Boolean isSetBaseTra = false;
		Boolean isQueryCon = false;
		List<SysCodeRelate> queryList = null;
		Map<String, Object> contrySaveMap = (Map<String, Object>) redisUtils.get(Constants.TRAVEL_ADDRESS_INFO_QUERY);
		if (contrySaveMap == null) {
			contrySaveMap = new HashMap<String, Object>();
			isQueryCon = true;
		} else {
			queryList = (List<SysCodeRelate>) contrySaveMap.get(planId);
			if (queryList == null) {
				isQueryCon = true;
			}
		}
		// List<SysCodeRelate> queryList =
		// (List<SysCodeRelate>)redisUtils.get(Constants.TRAVEL_ADDRESS_INFO_QUERY);
		if (!isQueryCon) {
			sr.setResult(queryList);
		} else {
			try {

				TQueryPolicyRequstDto requstDto = new TQueryPolicyRequstDto();
				requstDto.setId(planId); // 10159
				Map map = (Map) redisUtils.get(Constants.SYS_SERVICE_INFO);
				SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.TRAVEL_DESTINATION_URL.getUrlKey());
				requstDto.setPartnerAccountCode(sysServiceInfo.getUserName());
				requstDto.setFlowId(
						sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime());
				HttpEntity<TQueryPolicyRequstDto> requestEntity = new HttpEntity<TQueryPolicyRequstDto>(requstDto,
						RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));
				// log.info(JSON.toJSONString(requestEntity));
				// sysServiceInfo.setUrl("http://10.132.30.148:8850/queryPolicys.do");
				LinkedHashMap<String, String> response = (LinkedHashMap<String, String>) restTemplate.postForObject(sysServiceInfo.getUrl(),
						requestEntity, Object.class);

				Integer state = Integer.parseInt(response.get("resultCode"));
				if (ServiceResult.STATE_SUCCESS == state) {
					JSONArray arrayTra = JSONArray.parseArray(response.get("responseJson").toString());
					if (arrayTra == null || arrayTra.size() == 0) {
						isSetBaseTra = true;
					} else {
						List<TravelDto> travelList = arrayTra.toJavaList(TravelDto.class);
						List<SysCodeRelate> dballList = new ArrayList<SysCodeRelate>();
						TravelDto tra = null;
						for (int i = 0; i < travelList.size(); i++) {
							tra = travelList.get(i);
							SysCodeRelate codeRa = new SysCodeRelate();
							codeRa.setCodeCname1(tra.getCname());
							if (tra.getSchengen()) {
								codeRa.setCodeEname1(tra.getEname() + "/Schengen-States");
							} else {
								codeRa.setCodeEname1(tra.getEname());
							}
							dballList.add(codeRa);
						}
						contrySaveMap.put(planId, dballList);
						redisUtils.set(Constants.TRAVEL_ADDRESS_INFO_QUERY, contrySaveMap);
						sr.setResult(dballList);
					}

				}
			} catch (Exception e) {
				isSetBaseTra = true;
			}
		}

		if (isSetBaseTra) {
			List<SysCodeRelate> allList = (List<SysCodeRelate>) redisUtils.get(Constants.TRAVEL_ADDRESS_INFO);
			if (null != allList) {
				sr.setResult(allList);
			} else {
				Sort sort = new Sort(Direction.ASC, "codeType2");
				List<SysCodeRelate> dballList = codeRelateDao.findAll(new Specification<SysCodeRelate>() {
					@Override
					public Predicate toPredicate(Root<SysCodeRelate> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
						return cb.equal(root.get("codeType").as(String.class), "CountryCode");
					}
				}, sort);
				redisUtils.set(Constants.TRAVEL_ADDRESS_INFO, dballList);
				sr.setResult(dballList);
			}
		}

		return sr;
	}

	@Override
	public ServiceResult getCliaimsType(String code, String language) {
		ServiceResult sr = new ServiceResult();
		List<SysCodeRelate> sysCodeReList = codeRelateDao.getCliaimsType(code, language);
		List<SelectDto> seleList = new ArrayList<SelectDto>();
		StringBuilder dis = new StringBuilder();
		for (SysCodeRelate sysCodeRe : sysCodeReList) {
			if (dis.indexOf(sysCodeRe.getCodeType1()) == -1) {
				SelectDto sd = new SelectDto();
				dis.append(sysCodeRe.getCodeType1());
				sd.setKey(sysCodeRe.getCodeType());
				sd.setValue(sysCodeRe.getCodeType1());
				seleList.add(sd);
			}
		}
		sr.setResult(seleList);
		return sr;
	}

	@Override
	public ServiceResult addRisk(SysCodeRelate sysCodeRelate) {
		ServiceResult sr = new ServiceResult();
		sysCodeRelate.setCode("1");
		sysCodeRelate.setCodeType("SaleInitData");
		sysCodeRelate.setSerialNo(0);
		sysCodeRelate.setValidStatus("0");
		sysCodeRelate.setRiskCode("0");
		SysCodeRelate dbsysCodeRelate = codeRelateDao.save(sysCodeRelate);
		log.info("=======添加的险种返回=====" + sysCodeRelate.toString());
		sr.setResult(dbsysCodeRelate);
		return sr;
	}

	@Override
	public ServiceResult riskListPage(int pageNumber, int pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.ASC, "serialNo");
		Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, sort);
		sr.setResult(codeRelateDao.riskListPage("SaleInitData", pageable));
		return sr;
	}

	@Override
	public ServiceResult riskList() {
		ServiceResult sr = new ServiceResult();
		sr.setResult(codeRelateDao.getSaleInitData("SaleInitData"));
		return sr;
	}

	@Override
	public ServiceResult removeRisk(Integer id) {
		ServiceResult sr = new ServiceResult();
		codeRelateDao.deleteById(id);
		sr.setSuccess();
		return sr;
	}

	@Override
	public ServiceResult getCarlimitNo() {
		ServiceResult sr = new ServiceResult();
		Map<String, Map<String, SysCodeNode>> codeMap = (HashMap<String, Map<String, SysCodeNode>>) redisUtils.get(Constants.MAP_CODE);
		Map<String, SysCodeNode> limit = codeMap.get(Constants.LIMIT_LICENSE_NO);
		sr.setSuccess();
		sr.setResult(limit);
		// TODO Auto-generated method stub
		return sr;
	}

	@Override
	public List<SelectDto> getCodeRelateRisk(String codeType, String risk) {
		StringBuilder sql = new StringBuilder();
		// List<SelectDto> allList = (List<SelectDto>)
		// redisUtils.get(Constants.CAR_KIND_LIST+codeType+risk);
		// if (null != allList) {
		// return allList;
		// } else {
		List<SelectDto> allList = new ArrayList<SelectDto>();
		List<Map<String, Object>> listMap = null;
		sql.append("SELECT node.CODE_CNAME as name,node.`CODE` as code ");
		sql.append("FROM  ");
		sql.append("tb_sys_code_node AS node,  ");
		sql.append("tb_sys_code_risk AS risk  WHERE  ");
		sql.append("risk.CODE_TYPE = ?  AND node.CODE_TYPE=? AND node.`CODE` = risk.`CODE`  ");
		if (StringUtils.isNotBlank(risk)) {
			sql.append("AND risk.RISK_CODE = ?");
			listMap = readJdbcTemplate.queryForList(sql.toString(), new Object[] { codeType, codeType, risk });
		} else {
			listMap = readJdbcTemplate.queryForList(sql.toString(), new Object[] { codeType, codeType });
		}
		for (int i = 0; i < listMap.size(); i++) {
			Map<String, Object> map = listMap.get(i);
			SelectDto sele = new SelectDto();
			sele.setValue(map.get("name").toString());
			sele.setKey(map.get("code").toString());
			allList.add(sele);
		}
		// redisUtils.set(Constants.CAR_KIND_LIST, allList);
		return allList;

	}

	@Override
	public List<SelectDto> getCodeRelateBranch(String codeType, String branchCode) {
		List<SelectDto> seleList = new ArrayList<SelectDto>();
		List<SysCodeNode> nodeList = iSysCodeNodeDao.findByCodeBranch(codeType, branchCode);
		for (int i = 0; i < nodeList.size(); i++) {
			SysCodeNode codeNode = nodeList.get(i);
			SelectDto sele = new SelectDto();
			sele.setKey(codeNode.getCode());
			sele.setValue(codeNode.getCodeCname());
			seleList.add(sele);
		}

		return seleList;
	}

	@Override
	public ServiceResult queryCode(String level, String codeCode, int levelMax, int levelMin, boolean type) {
		ServiceResult sr = new ServiceResult();
		List<PrpdCode> list = null;
		List<SelectDto> seleDtoList = null;
		if (type) {
			String redisMark = Constants.OCCUPATIO_CATEGORY + level + codeCode + levelMax + levelMin;
			seleDtoList = (List<SelectDto>) redisUtils.get(redisMark);
			if (seleDtoList == null) {
				List<SysCodeRelate> codeList = codeRelateDao.getOccupatioCategory(Constants.OCCUPATIO_CATEGORY, codeCode);
				seleDtoList = new ArrayList<SelectDto>();
				for (int i = 0; i < codeList.size(); i++) {
					SysCodeRelate codeRelate = codeList.get(i);
					SelectDto se = new SelectDto();
					se.setName(codeRelate.getCodeCname1());
					se.setValue(codeRelate.getCode1() + ":" + codeRelate.getCodeCname1());
					seleDtoList.add(se);
				}
				redisUtils.set(redisMark, seleDtoList);
				sr.setSuccess();
				sr.setResult(seleDtoList);
			} else {
				sr.setSuccess();
				sr.setResult(seleDtoList);
			}
		} else {
			List<PrpdCode> redislist = (List<PrpdCode>) redisUtils.get(Constants.PRPD_CODE_INFO + level);
			if (null != redislist) {
				list = redislist;
			} else {
				CommonQueryRequestDTO request = new CommonQueryRequestDTO();
				request.setDocumentNo("OccupationSort");
				Map map = (Map) redisUtils.get(Constants.SYS_SERVICE_INFO);
				SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.QUERY_PRPD_CODE.getUrlKey());
				log.info("sysServiceInfo------------>:" + sysServiceInfo);
				request.setPartnerAccountCode(sysServiceInfo.getUserName());
				request.setFlowId(request.getPartnerAccountCode() + new Date().getTime());
				log.info("request------------>:" + BeanUtilExt.toJsonString(request));
				/*
				 * HttpHeaders headers = new HttpHeaders(); headers.add("account-code",
				 * sysServiceInfo.getUserName()); headers.add("request-time", String.valueOf(new
				 * Date().getTime())); headers.add("soa-token",
				 * pwdEncoder.encodePassword(sysServiceInfo.getPassword(), String.valueOf(new
				 * Date().getTime())));
				 */

				HttpEntity<CommonQueryRequestDTO> requestEntity = new HttpEntity<CommonQueryRequestDTO>(request,
						RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword()));

				TPrpdCodeResponseDto response = restTemplate.postForObject(sysServiceInfo.getUrl(), requestEntity, TPrpdCodeResponseDto.class);
				log.info("getSaleName response--->{}", response);
				List<PrpdCode> alllist = response.getPrpdCodes();
				List<PrpdCode> levellist = Lists.newArrayList();
				for (PrpdCode prpdCodes : alllist) {
					if (prpdCodes.getFlag().substring(0, 1).equals(level)) {
						levellist.add(prpdCodes);
					}
				}
				list = levellist;
				redisUtils.set(Constants.PRPD_CODE_INFO + level, levellist);
			}
			List<SelectDto> dblist1 = Lists.newArrayList();
			for (PrpdCode prpdCode : list) {
				SelectDto sd = null;
				if ("1".equals(level)) {
					if (prpdCode.getFlag().substring(0, 1).equals(level) && prpdCode.getCodeCName().indexOf("E通卡专用") == -1) {
						sd = new SelectDto();
						sd.setName(prpdCode.getCodeCName());
						sd.setValue(prpdCode.getCodeCode() + ":" + prpdCode.getCodeCName());
						dblist1.add(sd);
					}
				} else if ("2".equals(level)) {
					if (prpdCode.getFlag().substring(0, 1).equals(level) && prpdCode.getCodeCode().startsWith(codeCode)) {
						sd = new SelectDto();
						sd.setName(prpdCode.getCodeCName());
						sd.setValue(prpdCode.getCodeCode() + ":" + prpdCode.getCodeCName());
						dblist1.add(sd);
					}
				} else if ("3".equals(level)) {
					int workLevel = Integer.parseInt(prpdCode.getFlag().substring(prpdCode.getFlag().length() - 1));
					if (prpdCode.getFlag().substring(0, 1).equals(level) && prpdCode.getCodeCode().startsWith(codeCode) && levelMax >= workLevel
							&& workLevel >= levelMin) {
						sd = new SelectDto();
						sd.setName(prpdCode.getCodeCName());
						sd.setValue(prpdCode.getCodeCode() + ":" + prpdCode.getCodeCName());
						dblist1.add(sd);
					}
				}
			}
			sr.setResult(dblist1);
		}

		return sr;
	}

}
